/* Funciones de actualizacion de precio de articulos combo.
   Trabajan con un parametro nuevo AutoPreciosEnCombos que indica una variable de precio
   Si esta el parametro el sistema recalcula su precio de esa variable en base a los precios de la misma variable de sus 
   componentes cuando algun prexart de un componente varia o cuando se varia su formula. 
*/ 

CREATE OR REPLACE FUNCTION public.pre_valorCombo(
	varchar,
	integer)
    RETURNS numeric
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE 
AS $BODY$
DECLARE
	pCodPre			ALIAS FOR $1;
	pIdArt			ALIAS FOR $2;
	vValor          numeric;
BEGIN

/* Devuelve el valor de un articulo a partir de sus componentes en la variable de precios indicada */

	vValor := (SELECT SUM(artfabdet.cantidad * artfabdet.porcpre / 100 * pre_obtenerprecio(pCodPre, artfabdet.idart, null,null)) as Valor
		       FROM artfab
		       INNER JOIN artfabdet ON artfab.id = artfabdet.idartfab
		       WHERE artfab.idart = pIdArt);
	return vValor;
END;
$BODY$;

ALTER FUNCTION public.pre_valorCombo(varchar, integer)
    OWNER TO abacouser;
	
CREATE OR REPLACE FUNCTION public.get_parametro_ini(varchar)
    RETURNS varchar
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE 
AS $BODY$
DECLARE
	pParametro		ALIAS FOR $1;
	vValor          varchar;
BEGIN

/* Devuelve el valor de un parametro en el campo ini de ambcfg */

    if (position(pParametro in (SELECT INI FROM AMBCFG)) > 0) THEN
		vValor := 	(select trim(substring(substring(ini, position(pParametro in ini) + length(pParametro) + 1, 100), 1, 
					position(cast(chr(10) as varchar) in substring(ini, position(pParametro in ini) + length(pParametro) + 1, 100)) - 1))
					from ambcfg);
	ELSE
		vValor := '';
	END IF;
	return vValor;
END;
$BODY$;

ALTER FUNCTION public.get_parametro_ini(varchar)
    OWNER TO abacouser;
		

-- FUNCTION: public.tg_prexart_familia()

-- DROP FUNCTION public.tg_prexart_familia();

DROP TRIGGER IF EXISTS prexart_familia ON public.prexart;

CREATE TRIGGER prexart_familia
    AFTER INSERT OR UPDATE 
    ON public.prexart
    FOR EACH ROW
    EXECUTE PROCEDURE public.tg_prexart_familia();

CREATE OR REPLACE FUNCTION public.tg_prexart_familia()
    RETURNS trigger
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE NOT LEAKPROOF
AS $BODY$
DECLARE
vEsHijo      boolean;
vEsFormador  	boolean;
vCodPre      	varchar;
vIdPre       	integer;
vNuevoValor  	numeric;
vViejoValor  	numeric;
vCodPreAutoprecio varchar;
BEGIN
/* Actualiza los precios de los articulos padre del articulo modificado */

IF ((TG_OP = 'INSERT') OR (TG_OP = 'UPDATE')) THEN
    /*Si encuentra algun registro en ArtFabDet quiere decir es parte de un articulo compuesto*/
	SELECT Exists(SELECT * FROM ArtFabDet WHERE IdArt = New.IdArt) into vEsHijo;
	IF 	vEsHijo THEN
		vCodPreAutoprecio := get_parametro_ini('AutoPrecioEnCombos');
		IF vCodPreAutoprecio <> '' THEN
		   /* En este caso no importa cual es la variable que modifico, recalculo el precio del combo para la variable del parametro */
		   vIdPre := (SELECT id FROM PRE WHERE COD = vCodPreAutoprecio);
		   /* Si el combo no tiene prexart con esta variable, inserto el registro sin valor */
		   INSERT INTO prexart(IdPre, IdArt, valor)
		   SELECT distinct vIdPre, artfab.idart, 0.00
		   FROM artfab
		   INNER JOIN artfabdet ON artfab.id = artfabdet.idartfab
		   WHERE artfabdet.idart = New.idArt AND NOT EXISTS (SELECT * FROM prexart WHERE prexart.idart = artfab.idart and prexart.idpre = vIdPre);
		   /* Update siempre para todos los combos donde esta este articulo presente */
		   UPDATE prexart 
		   SET valor = pre_ValorCombo(vCodPreAutoprecio, artfab.idart)
		   FROM (select distinct artfab.idart
				 FROM artfab
		         INNER JOIN artfabdet ON artfab.id = artfabdet.idartfab
		         WHERE artfabdet.idart = New.idArt) as artfab
		   WHERE artfab.idart = prexart.idart and prexart.idPre = vIdPre;
        ELSE 
		IF Exists(SELECT * FROM ArtC WHERE IdArt = New.IdArt AND TipoArtA = 'ESP' and CodArtR = 'P') THEN
            /*Si el articulo padre ya tiene un PrexArt con la variable de precio que se esta modificando*/
			vIdPre 		:= New.IdPre;
			vNuevoValor := New.Valor;
			IF (TG_OP = 'UPDATE') THEN
				vViejoValor := Old.Valor;
			ELSE
				vViejoValor := 0;
			END IF;
			UPDATE PrexArt 
			   SET Valor = Valor + (vNuevoValor - vViejoValor) * ArtFabDet.Cantidad
			FROM ArtFab,ArtFabDet
			WHERE 	(ArtFabDet.IdArtFab = ArtFab.Id) AND
					(PrexArt.IdArt = ArtFab.IdArt) AND
					(ArtFabDet.IdArt = New.IdArt) AND
					(PrexArt.IdPre = vIdPre);
/* Si el articulo padre no tiene un PrexArt con la variable de precio que se esta modificando la inserta */
			INSERT INTO PrexArt (IdPre, IdArt, Valor)
				SELECT vIdPre, ArtFab.IdArt, (vNuevoValor - vViejoValor) * ArtFabDet.Cantidad * ArtFabDet.porcpre / 100
				FROM ArtFab
				INNER JOIN ArtFabDet ON ArtFabDet.IdArtFab = ArtFab.Id
				LEFT JOIN PrexArt ON (ArtFab.IdArt = PrexArt.IdArt) AND (PrexArt.IdPre = vIdPre)
				WHERE (PrexArt.IdArt IS NULL) AND (ArtFabDet.IdArt = New.IdArt) ;
		END IF;
		END IF;
	END IF;
END IF;

RETURN NEW;

END;
$BODY$;

ALTER FUNCTION public.tg_prexart_familia()
    OWNER TO abacouser;


DROP TRIGGER IF EXISTS pre_ins_upd_recalculoprecios ON public.pre;

CREATE TRIGGER pre_ins_upd_recalculoprecios
    AFTER INSERT OR UPDATE 
    ON public.pre
    FOR EACH ROW
    EXECUTE PROCEDURE public.tg_pre_ins_upd_recalculoprecios();

CREATE OR REPLACE FUNCTION public.tg_pre_ins_upd_recalculoprecios()
    RETURNS trigger
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE NOT LEAKPROOF
AS $BODY$
DECLARE
vCodPre  varchar;
vIdPre   integer;
BEGIN
  
/* Recalcula los precios de los articulos combo de la variable del parametro AutoPrecioEnCombos 
   (podria ser que no fuera la que se esta modificando)
*/

  vCodPre := get_parametro_ini('AutoPrecioEnCombos');
  IF vCodPre <> '' THEN
	vIdPre	:= (SELECT id FROM PRE WHERE COD = vCodPre);
	UPDATE prexart 
	SET valor = pre_valorCombo(vCodPre, prexart.idArt)
	FROM artfab
	WHERE artfab.idart = prexart.idart AND prexart.idPre = vIdPre; 
  END IF;

  RETURN NEW;
END;
$BODY$;

ALTER FUNCTION public.tg_pre_ins_upd_recalculoprecios()
    OWNER TO abacouser;

DROP TRIGGER IF EXISTS artfabdet_precio ON public.artfabdet;

CREATE TRIGGER artfabdet_precio
    AFTER INSERT OR DELETE OR UPDATE 
    ON public.artfabdet
    FOR EACH ROW
    EXECUTE PROCEDURE public.tg_artfabdet_precio();
	
CREATE OR REPLACE FUNCTION public.tg_artfabdet_precio()
    RETURNS trigger
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE NOT LEAKPROOF
AS $BODY$
DECLARE
vIdArtPadre  	integer;
vIdPre			integer;
vCodPre         varchar;
BEGIN

/* Recalcula los precios del articulo padre cuando se modifica uno de sus renglones.
   Si esta el parametro AutoPrecioEnCombos 
*/


  vCodPre := get_parametro_ini('AutoPrecioEnCombos');
  IF vCodPre <> '' THEN
  	 vIdPre		 :=  (SELECT id FROM PRE WHERE COD = vCodPre);
	 IF (TG_OP = 'INSERT') OR (TG_OP = 'UPDATE') THEN
	     vIdArtPadre :=  (SELECT idart FROM artfab where New.IdArtFab = artfab.id);
	 ELSE
	     vIdArtPadre :=  (SELECT idart FROM artfab where Old.IdArtFab = artfab.id);
	 END IF;     
	 
	 IF NOT EXISTS (SELECT * FROM prexart WHERE prexart.idart = vIdArtPadre and prexart.idpre = vIdPre) THEN
   	 	INSERT INTO prexart(IdPre, IdArt, valor) VALUES (vIdPre, vIdArtPadre, 0.00);
	 END IF;

     UPDATE prexart SET valor = pre_valorCombo(vCodPre, vIdArtPadre)
	 WHERE prexart.idart = vIdArtPadre and prexart.idPre = vIdPre;
	 
  END IF;
  IF (TG_OP = 'INSERT') OR (TG_OP = 'UPDATE') THEN
     RETURN NEW;
  ELSE
     RETURN OLD;
  END IF;
  

END;
$BODY$;

ALTER FUNCTION public.tg_artfabdet_precio()
    OWNER TO abacouser;	

-- =====================================================

SELECT aaVersion('488.05','488.04');

-- =====================================================

